package cn.net.isir.service;

import cn.net.isir.dao.*;
import cn.net.isir.entity.*;
import cn.net.isir.utils.DateUtils;
import cn.net.isir.utils.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

/**
 * @author liuxubo
 * @filename CRMUserManagerService.java
 * @package cn.net.isir.service
 * @email lxb@isir.net.cn
 * @date 2019/03/12
 * @comment
 * @since 1.8
 */
@Service
public class CRMUserManagerService {
    @Resource
    private UserValidInfoDao userValidInfoDao;
    @Resource
    private OrganizationsDao organizationsDao;
    @Resource
    private UserOrgDao userOrgDao;
    @Resource
    private TurnShopDao turnShopDao;
    @Resource
    private UserRoleDao userRoleDao;
    @Resource
    private RoleDao roleDao;
    @Resource
    private UserDao userDao;


    /**
     * 获取当前组织机构的子组织机构
     *
     * @param orgId 父级组织机构
     * @return 组织机构列表
     */
    public List<Organizations> getOrgListByOrgId(String orgId) {
        return organizationsDao.selectSubList(orgId);
    }

    /**
     * 获取当前用户下的所有组织机构(不包括自己本身所在的组织机构)
     *
     * @param userId 组织机构
     * @return 结果
     */
    public List<Organizations> getOrgListByUserId(String userId) {
        if (StringUtils.isBlank(userId)) {
            return null;
        }
        User user = userDao.selectByPrimaryKey(userId);
        if (user == null) {
            return null;
        }
        UserOrg userOrg = new UserOrg();
        userOrg.setUserId(userId);
        //获取当前用户的所有组织机构
        List<UserOrg> userOrgList = userOrgDao.selectList(userOrg);
        List<Organizations> orgList = new ArrayList<>();
        for (UserOrg org : userOrgList) {
            orgList.addAll(organizationsDao.selectSubList(org.getOrgId()));
        }
        Set<String> orgIdSet = new HashSet<>();
        orgList.forEach(item -> orgIdSet.add(item.getId()));
        List<Organizations> newOrgList = new ArrayList<>();
        orgIdSet.forEach(item -> orgList.forEach(item2 -> {
            if (item.equals(item2.getId())) {
                newOrgList.add(item2);
            }
        }));
        return newOrgList;
    }

    /**
     * 根据组织机构id,查询所有销售人员列表(包括本级组织机构下的直接人员)
     *
     * @param ids 组织机构id,多个使用逗号分隔
     * @return 销售人员id列表
     */
    public Set<String> getSalesmanIdByOrgId(String ids) {
        // 查询所有组织机构
        List<Organizations> organizationsList = new ArrayList<>();
        for (String s : ids.split(",")) {

            List<Organizations> orgs = organizationsDao.selectSubList(s);
            // 增加本身
            Organizations o = organizationsDao.selectByPrimaryKey(s);
            if (o != null) {
                orgs.add(o);
            }
            // 去重
            for (Organizations org : orgs) {
                boolean isExist = false;
                for (Organizations organizations : organizationsList) {
                    if (organizations.getId().equals(org.getId())) {
                        isExist = true;
                    }
                }
                if (!isExist) {
                    organizationsList.add(org);
                }
            }
        }
        // 增加同级组织机构
        // 查询所有组织机构下的人员
        Set<String> userSet = new HashSet<>();
//        for (Organizations organizations : organizationsList) {
//            UserOrg userOrg = new UserOrg();
//            userOrg.setOrgId(organizations.getId());
//            // 查询所有组织机构关联关系
//            List<UserOrg> userOrgList = userOrgDao.selectList(userOrg);
//            for (UserOrg org : userOrgList) {
//                userSet.add(org.getUserId());
//            }
//        }

        String orgIds = StringUtils.collectionsToCommas(organizationsList, Organizations::getId);
        List<UserOrg> userOrgList = userOrgDao.queryListByOrgIds(orgIds);
        userOrgList.forEach(uo->userSet.add(uo.getUserId()));

        return userSet;
    }

    /**
     * 根据用户id查询销售人员ID(自己管理下的所有人员,不包括自己同组织机构的人员)
     *
     * @param userId 用户id
     * @return 用户列表
     */
    public Set<String> getSalesmanIdByUserId(String userId) {
        // 获取所有子级组织机构
//        List<Organizations> orgList = getOrgListByUserId(userId);
//        Set<String> userIds = new HashSet<>();
//
//        if (orgList != null) {
//            for (Organizations organizations : orgList) {
//                //获取组织机构的所有人并加进来
//
//                UserOrg userOrg = new UserOrg();
//                userOrg.setOrgId(organizations.getId());
//                // 查询所有组织机构关联关系
//                List<UserOrg> userOrgList = userOrgDao.selectList(userOrg);
//                for (UserOrg org : userOrgList) {
//                    userIds.add(org.getUserId());
//                }
////                userIds.addAll(getSalesmanIdByOrgId(organizations.getId()));
//            }
//        }
//        return userIds;
        List<String> userIdList = userOrgDao.querySubUserIdsByUserId(userId);
        return new HashSet<>(userIdList);
    }

    /**
     * 获取销售人员有效期时间段列表
     *
     * @param salesmanId 销售人员ID
     * @return 有效时间列表
     */
    public List<TimeRange> getTimeRangeList(String salesmanId) {
        List<TimeRange> timeRangeList = new ArrayList<>();
        UserValidInfo userValidInfo = new UserValidInfo();
        userValidInfo.setUserId(salesmanId);
        List<UserValidInfo> list = userValidInfoDao.selectList(userValidInfo);
        // 是否已经开始
        boolean isStarted = false;

        TimeRange timeRange = null;

        // 为了保持开始时间与结束时间一一相对,如果最后一条记录不是结束时间,则手动添加一个结束时间(默认为当天23:59:59)
        if (list.size() > 0) {
            UserValidInfo validInfo = list.get(list.size() - 1);
            if (validInfo.getChangeStatus() == 1) {
                UserValidInfo info = new UserValidInfo();
                info.setChangeStatus(0);
                info.setChangeTime(DateUtils.getCurrentDayEndTime());
                list.add(info);
            }
        }

        // 增加记录
        for (UserValidInfo info : list) {
            // 检测到开始,则设置为开始
            if (info.getChangeStatus() == 1) {
                isStarted = true;
            }
            // 已经开始了,并且遇到开始节点,则开始记录
            if (isStarted && info.getChangeStatus() == 1) {
                // 判断如果有多个开始节点,首次(timeRange is null)才设置时间点
                if (timeRange == null) {
                    timeRange = new TimeRange();
                    timeRange.setStartTime(info.getChangeTime());
                }
            }
            // 已经开始,并且遇到结束节点,才算结束
            // 如果一开始就是0,则isStarted是false,则不会加入列表
            // 如果0之后有多个0,则因为第一次0的时候isStarted设置为false了,后来的0都不会加入列表
            if (isStarted && info.getChangeStatus() == 0) {
                if (timeRange != null) {
                    timeRange.setEndTime(info.getChangeTime());
                    timeRangeList.add(timeRange);
                    isStarted = false;
                    timeRange = null;
                }
            }
        }
        return timeRangeList;
    }

    /**
     * 根据父级用户id查询子用户以及有效时间列表(不包括自己同组织机构的)
     *
     * @param userId 父级id
     * @return 列表
     */
    public Map<String, List<TimeRange>> getSalesmanTimeRangeMapByPUserId(String userId) {
        //根据用户id查询销售人员ID(自己管理下的所有人员,不包括自己同组织机构的人员)
        Set<String> saleIds = getSalesmanIdByUserId(userId);
        Map<String, List<TimeRange>> map = new HashMap<>();
        for (String saleId : saleIds) {
            map.put(saleId, getTimeRangeList(saleId));
        }
        return map;
    }

    /**
     * 获取已转出店铺列表
     *
     * @return 转出店铺的ID列表(逗号分隔)
     */
    public String getTurnedShopIds() {
       StringBuilder turnShopIds = new StringBuilder();
        List<TurnShop> turnShopList = turnShopDao.selectList(null);
        turnShopList.forEach(item -> turnShopIds.append(item.getShopId()).append(","));
        if (turnShopIds.length() > 0) {
          return turnShopIds.substring(0, turnShopIds.length() - 1);
        }
        return "";
    }

    /**
     * 获取同级和父级(组织机构)所有创建的角色(因为角色可能多个管理员共同管理,所以要支持多级管理)
     *
     * @param userId 用户id
     * @return
     */
    public List<Role> getRolesByUserId(String userId) {
        if (StringUtils.isBlank(userId)) {
            return null;
        }
        Set<String> userSet = new HashSet<>();
        // 添加本用户
        userSet.add(userId);
        // 添加本人下的所有子用户
        userSet.addAll(getSalesmanIdByUserId(userId));
        // 获取本人的组织机构
        UserOrg userOrg = new UserOrg();
        userOrg.setUserId(userId);
        userOrg = userOrgDao.selectOne(userOrg);
        if (userOrg != null) {
            // 获取本组织机构下的所有用户
            UserOrg userOrg1 = new UserOrg();
            userOrg1.setOrgId(userOrg.getOrgId());
            List<UserOrg> userOrgList = userOrgDao.selectList(userOrg1);
            // 添加本机构下的直接用户
            for (UserOrg org : userOrgList) {
                userSet.add(org.getUserId());
            }
            // 添加本机构下的所有子用户
            userSet.addAll(getSalesmanIdByOrgId(userOrg.getOrgId()));
        }
        // 获取所有角色ID
        HashSet<String> roleSet = new HashSet<>();
        for (String usId : userSet) {
            Role role = new Role();
            role.setCreateUser(usId);
            List<Role> roles = roleDao.selectList(role);
            roles.forEach(i -> roleSet.add(i.getId()));
        }
        // 查询角色实体并返回
        List<Role> roles = new ArrayList<>();
        roleSet.forEach(i -> roles.add(roleDao.selectByPrimaryKey(i)));
        return roles;
    }

    /**
     * 返回当前组织机构的所有父级组织机构(包括自己)
     *
     * @param orgId 当前组织机构
     * @return 父级组织机构列表
     */
    public List<Organizations> getParentsOrgByOrgId(String orgId) {
        List<Organizations> result = new ArrayList<>();
        String currentParentId = orgId;
        while (!"-1".equals(currentParentId)) {
            Organizations org = organizationsDao.selectByPrimaryKey(currentParentId);
            result.add(org);
            currentParentId = org.getPid();
        }
        return result;
    }

    /**
     * 获取当前用户的所属机构
     *
     * @param userId 当前用户
     * @return 返回所属机构
     */
    public Organizations getOrgByUserId(String userId) {
        UserOrg uo = new UserOrg();
        uo.setUserId(userId);
        uo = userOrgDao.selectOne(uo);
        if (uo != null) {
            return organizationsDao.selectByPrimaryKey(uo.getOrgId());
        }
        return null;
    }
}
